/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package chameleon.model.game;

import chameleon.model.NuGatStructure.symbTable.SymbTable;
import chameleon.model.NuGatStructure.prop.PropDbGame;
import chameleon.model.NuGatStructure.opt.OptGame;
import chameleon.model.NuGatStructure.fsm.GameBddFsm;
import chameleon.model.NuGatStructure.fsm.FsmBuilder;
import chameleon.model.NuGatStructure.fsm.BddFsm;
import chameleon.model.NuGatStructure.enc.BoolEnc;
import chameleon.model.NuGatStructure.enc.BddEnc;
import chameleon.model.NuGatStructure.strategy.StructCheckLTLGameSF07;
import chameleon.model.NuGatStructure.strategy.GameStrategy;
import chameleon.gameSolver.NuGat.NuGatInterface;
import chameleon.model.game.transition.TransitionRelationDescription;
import java.io.IOException;
import java.util.Hashtable;

/**
 * This class represent the game structure build on a smv file given on input.
 *
 * At the moment this class is just used to build the NuGat structure and after
 * Chameleon directly use NuGat structure.
 *
 * This class is an HasTable that contains some decoration (@GameDecorator).
 * Maximum one instance of each decoration is present in the structure.
 */

/**
 *
 * @author simon
 */
public class Game {

    

    @SuppressWarnings("UseOfObsoleteCollectionType")
    private Hashtable decorations_;
    private NuGatInterface nugat_;

    //*************************** CONSTRUCTOR ******************************//
    public Game(){
        decorations_ = new Hashtable();
    }

    //******************* GETTER *****************************************//

    /**
     * Return the smv file that represent the current game
     *
     * @return
     * @throws IOException
     */

    public SmvFile  getSmvFile() throws IOException{
        SmvFile smv = (SmvFile) decorations_.get(Tag.SMVTRANS);
        if ( smv != null)
            return smv;
        else
            throw new IOException("Decoration not present");
    }

    /**
     *
     * Return the transition relation corresponding to the given tag.
     *
     * @param tag
     * @return
     */

    public TransitionRelationDescription getTransition(int tag){
        return (TransitionRelationDescription) decorations_.get(tag);
    }

    /**
     * Return the transition relation.
     * @return
     */

    public TransitionRelationDescription getTransition(){
        return (TransitionRelationDescription) decorations_.get(Tag.TRANSITION);
    }

    /**
     * Return the BddFsm that represent the transition relation for Player 1.
     * @return
     */

    public BddFsm getBddFsmP1(){
        GameBddFsm gameBddFsm = getGameBddFsm(); 
        return gameBddFsm.getTransitionRelationPlayer1();
    }

    /**
     * Return the BddFsm that represent the transiton relation for Player 2.
     * @return
     */

    public BddFsm getBddFsmP2(){
        GameBddFsm gameBddFsm = getGameBddFsm(); 
        return gameBddFsm.getTransitionRelationPlayer2();
    }

    /**
     * Return the GameBddFsmDecorator that represent the current game.
     * @return
     */

    public GameBddFsm getGameBddFsm(){
        GameBddFsmDecorator dec = (GameBddFsmDecorator) decorations_.get(Tag.GAME_BDD_FSM);
        return dec.getGameBddFsm() ;
    }
    
    public GameStrategy getStrategy(){
        StrategyDecorator dec = (StrategyDecorator) decorations_.get(Tag.STRATEGY);
        return dec.getStrategy();
    }
    
    public GameStrategy getInitStrategy(){
        StrategyDecorator dec = (StrategyDecorator) decorations_.get(Tag.INIT_STRATEGY);
        return dec.getStrategy();
    }
    
    public StructCheckLTLGameSF07 getCls(){
        ClsDecorator dec = (ClsDecorator) decorations_.get(Tag.CLS);
        return dec.getCls();
    }

    //********************** GLOBAL GETTER *******************************//
    
    public BddEnc getBddEncoding(){
        return new BddEnc(nugat_.Enc_get_bdd_encoding(),nugat_);
    }
    
    public BoolEnc getBoolEncoding(){
        return new BoolEnc(nugat_.Enc_get_bool_encoding(),nugat_);
    }
    
    public OptGame getOptsHandlerInstance(){
        return new OptGame(nugat_.OptsHandler_get_instance(),nugat_);
    }
    
    public FsmBuilder getGlobalFsmBuilder(){
        return new FsmBuilder(nugat_.Compile_get_global_fsm_builder(), nugat_);
    }
    
    public SymbTable getGlobalSymbTable(){
        return new SymbTable(nugat_.Compile_get_global_symb_table(),
                getBddEncoding(),
                getBoolEncoding()
                ,nugat_);
    }
    
    public PropDbGame getPropDatabase(){
        return new PropDbGame(nugat_.PropPkg_get_prop_database(), nugat_);
    }
    
    //******************* SETTER ****************************************//
    
    public void setNuGatInterface(NuGatInterface nugat){
        nugat_ = nugat;
    }
    
    //******************* DECORATION METHOD ******************************//

    /**
     * Add the given decoration to the game structure using the decoration'tag.
     *
     * @param decoration
     */

    public void addDecoration (GameDecorator decoration){
        decorations_.put(decoration.getTag(), decoration);
    }


    /**
     * Add the given decoration with the given tag to the game structure.
     *
     * @param decoration
     * @param tag
     */

    public void addDecoration (GameDecorator decoration, int tag){
        decorations_.put(tag,decoration);
    }

    /**
     * delete the decoration corresponding to the given tag.
     *
     * @param tag
     */

    public void deleteDecoration (int tag){
        decorations_.remove(tag);
    }

}
